package com.demo.camunda.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.PageUtil;
import com.demo.camunda.RequestBO.HolidayBO;
import com.demo.camunda.camundaBO.TaskBO;
import com.demo.camunda.camundaBO.UserBO;
import com.demo.camunda.service.impl.AddMultiInstance;
import com.demo.camunda.util.CommonResult;
import com.demo.camunda.variableBO.EvectionBO;
import org.camunda.bpm.engine.*;
import org.camunda.bpm.engine.identity.User;
import org.camunda.bpm.engine.repository.Deployment;
import org.camunda.bpm.engine.runtime.ActivityInstance;
import org.camunda.bpm.engine.runtime.ProcessInstance;
import org.camunda.bpm.engine.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.demo.camunda.util.PageUtil.startPage;

@RestController
@RequestMapping("/TestController")
public class TestController {

    private static Logger logger = LoggerFactory.getLogger(TestController.class);

    @Resource
    private RepositoryService repositoryService;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private ManagementService managementService;
    @Resource
    private TaskService taskService;
    @Resource
    private ProcessEngine processEngine;
    @Resource
    private IdentityService identityService;

    @Resource
    private AddMultiInstance addMultiInstance;


    //首先部署一个流程
    @PostMapping("/deploy")
    public void deploy() {
        String path = "C:\\Users\\WH2206003\\Desktop\\camunda\\用户测试.bpmn";
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(path);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        Deployment deploy = repositoryService.createDeployment()
                //此处必须以 .bpmn結尾
                .addInputStream("用户测试.bpmn", fileInputStream)
                .name("用户测试")
                .deploy();
        try {
            fileInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        logger.info(deploy.getName());
        logger.info(deploy.getId());
    }

    //然后启动刚才部署的流程
    @PostMapping("/startByInstanceId")
    public String startByInstanceId(@RequestBody HolidayBO holidayBO) {
        Map<String, Object> map = new HashMap<>();
        EvectionBO evectionBO = new EvectionBO();
        evectionBO.setDescription(holidayBO.getDescription());
        evectionBO.setDay(holidayBO.getDay());
        evectionBO.setName(holidayBO.getName());
        map.put("evection", evectionBO);

//        if(holidayBO.getAssigneeList() != null){
//            map.put("assigneeList",holidayBO.getAssigneeList());
//        }
//        if(holidayBO.getAssigneeAgainList() != null){
//            map.put("assigneeAgainList",holidayBO.getAssigneeAgainList());
//        }
        List assigneeAgainList = new ArrayList();
        assigneeAgainList.add("user5");
        assigneeAgainList.add("user6");
        List assigneeList = new ArrayList();
        assigneeList.add("user2");
        assigneeList.add("user3");
        assigneeList.add("user4");
        map.put("assigneeList", assigneeList);
        map.put("assigneeAgainList", assigneeAgainList);
        holidayBO.setProInsId("Process_1656983507394:10:bda43a20-fc37-11ec-9f58-f4a4757e3c26");

        ProcessInstance processInstance = runtimeService.startProcessInstanceById(holidayBO.getProInsId(), map);
        String id = processInstance.getId();
        logger.info(id);
        return id;

    }

    //创建用户
    @PostMapping("/createUser")
    public void createUser(@RequestBody UserBO userBO) {
        User user = identityService.newUser(userBO.getId());
        user.setId(userBO.getId());
        user.setFirstName(userBO.getFirstName());
        user.setLastName(userBO.getLastName());
        user.setPassword(userBO.getPassword());
        identityService.saveUser(user);
    }

    //查询用户的待完成任务
    @PostMapping("/queryUserTask")
    public Map<String, Object> queryUserTask(Integer pageIndex, String userId) {

        List<Task> taskList = taskService.createTaskQuery().taskAssignee(userId).list();

        List<TaskBO> listBO = new ArrayList<>();
        taskList.stream().forEach(o -> {
            TaskBO taskBO = new TaskBO();
            taskBO.setAssignee(o.getAssignee());
            taskBO.setName(o.getName());
            taskBO.setId(o.getId());
            listBO.add(taskBO);
        });
        Map<String, Object> map = startPage(pageIndex, listBO);
        return map;
    }

    //重启实例
    @PostMapping("/restartInstance")
    public void restartInstance(String processDefinitionId) {
        runtimeService.restartProcessInstances(processDefinitionId);
    }

    //撤回示例
    //
    @PostMapping("/recallInstance")
    public CommonResult recallInstance(String processInstanceId) {
        ActivityInstance activity = runtimeService.getActivityInstance(processInstanceId);
        runtimeService.createProcessInstanceModification(processInstanceId)
                //关闭相关任务
                .cancelActivityInstance(activity.getId())
                //.setAnnotation("发起人撤回")
                //启动目标活动节点
                //.startBeforeActivity("root")
                .execute();
        return CommonResult.success();
    }


    //查询流程状态
    @PostMapping("/getStatus")
    public ProcessInstance getStatus(String processInstanceId) {
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        return processInstance;
    }

    //完成指定id的任务
    @PostMapping("/completeTask/{id}")
    public CommonResult completeTask(@PathVariable  String id) {
        processEngine.getTaskService() // 任务相关Service
                .complete(id); // 指定要完成的任务ID

        return CommonResult.success();
    }

    @PostMapping("/queryNowTask")
    public List<TaskBO> queryNowTask(String id, String userId) {
        List<Task> list = taskService.createTaskQuery().processInstanceId(id).taskAssignee(userId).list();
        List<TaskBO> listBO = new ArrayList<>();
        list.stream().forEach(o -> {
            TaskBO taskBO = new TaskBO();
            taskBO.setAssignee(o.getAssignee());
            taskBO.setName(o.getName());
            taskBO.setId(o.getId());
            taskBO.setProcessDefinitionId(o.getProcessDefinitionId());
            taskBO.setProcessInstanceId(o.getProcessInstanceId());
            taskBO.setTaskDefinitionKey(o.getTaskDefinitionKey());
            listBO.add(taskBO);
        });


        return listBO;
    }


    //委托
    @PostMapping("/delegateTask")
    public boolean delegateTask(String taskId, String loginName) {
        taskService.delegateTask(taskId, loginName);
        return true;
    }

    //此方法只适用于 并行节点中 多添加一个用户审批
    @PostMapping("/countersign")
    public void countersign(String activityId, String processInstanceId, String userId) {
        runtimeService.createProcessInstanceModification(processInstanceId).
                startBeforeActivity(activityId).setVariable("assignee", userId).execute();
//        List<VariableInstance> lists = runtimeService.createVariableInstanceQuery()
//                .processInstanceIdIn(processInstanceId)
//                .orderByVariableName()
//                .desc()
//                .list();
//        lists.stream().forEach(o -> {
//            if(o.getProcessInstanceId().equals(processInstanceId) && o.getName().equals("assigneeAgainList")){
//                runtimeService.setVariable(o.getExecutionId(),"assignee",userId);
//            }
//        });


    }


    //征询
    @PostMapping("/consult")
    public void consult(String userQ, String userP, String id) {
        Task task = taskService.createTaskQuery().processInstanceId(id)
                .taskAssignee(userQ)
                .singleResult();
        taskService.setAssignee(task.getId(), userP);
        //征询的问题
        taskService.setVariableLocal(task.getId(), "commend", "请示");
        //对被征询者做出记录
        taskService.setVariableLocal(task.getId(), "targetUser", userP);
        //对发出征询者做出记录
        taskService.setVariableLocal(task.getId(), "originUser", userQ);

    }

    @PostMapping("/queryConsult")
    public void queryConsult(String userId, String id) {
        Task task = taskService.createTaskQuery().processInstanceId(id)
                .taskAssignee(userId)
                .singleResult();
        String reply = (String) taskService.getVariableLocal(task.getId(), "reply");
        if (reply != null) {
            logger.info(reply);
            taskService.removeVariable(task.getId(), "reply");
        }

    }


    @PostMapping("/reply")
    public void reply(String userId, String processInstanceId) {
        Task task = taskService.createTaskQuery().processInstanceId(processInstanceId)
                .taskAssignee(userId)
                .singleResult();
        String originUser = (String)
                taskService.getVariableLocal(task.getId(), "originUser");
        logger.info("征询发起人" + originUser);
        logger.info((String) taskService.getVariableLocal(task.getId(), "commend"));
        taskService.setVariableLocal(task.getId(), "reply", "可以批准");
        taskService.setAssignee(task.getId(), originUser);
        taskService.removeVariable(task.getId(), "targetUser");
        taskService.removeVariable(task.getId(), "originUser");
    }


    //查询执行流程
    @PostMapping("/queryExecution")
    public void queryExecution(String processInstanceId) {
        addMultiInstance.execute(processInstanceId);
    }


}
